#import "ShrinkTreeViewController.h"
#import "MServerDAO.h"
#import "MCFunction.h"
#import "Three20/Three20.h"
#import "MCUIToolkit.h"

@implementation MCTabStrip
- (void)setTabItems:(NSArray*)tabItems {
	[_tabItems release];
	_tabItems =  [tabItems retain];
	
	for (int i = 0; i < _tabViews.count; ++i) {
		TTTab* tab = [_tabViews objectAtIndex:i];
		[tab removeFromSuperview];
	}
	
	[_tabViews removeAllObjects];
	
	if (_selectedTabIndex >= _tabViews.count) {
		//_selectedTabIndex = 0;
	}
	_selectedTabIndex = NSIntegerMax-1;
	for (int i = 0; i < _tabItems.count; ++i) {
		TTTabItem* tabItem = [_tabItems objectAtIndex:i];
		TTTab* tab = [[[TTTab alloc] initWithItem:tabItem tabBar:self] autorelease];
		[tab setStylesWithSelector:self.tabStyle];
		[tab addTarget:self action:@selector(tabTouchedUp:) forControlEvents:UIControlEventTouchUpInside];
		[self addSubview:tab];
		[_tabViews addObject:tab];
		//if (i == _tabItems.count-1) {
			tab.selected = YES;
		//}
	}
	
	[self setNeedsLayout];
}
@end


@interface ShrinkTreeViewController (Private)
- (void)removeChildTreeNodes:(NSString *)positionId;
- (void)onSelectedTreeNode:(NSMutableDictionary*)treeNode;
- (void)addTabBarHeader:(NSArray*)items;
- (void)checkAndAddControl;
@end

@implementation ShrinkTreeViewController
@synthesize treeData;
@synthesize treeNodes;
@synthesize treeNodePosition;
@synthesize fatherId;
@synthesize strSelectedIndex;
@synthesize treeNodesItemBack;

- (void)registerNotifications
{
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(TextFieldTextChange:)
												 name:UITextFieldTextDidChangeNotification object:nil];
}

- (void)unregisterNotifications
{
	[[NSNotificationCenter defaultCenter] removeObserver:self 
													name:UITextFieldTextDidChangeNotification 
												  object:nil];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
	self.title = [treeData objectForKey:@"lbl"];
	self.treeNodes = [treeData objectForKey:@"ns"];
	self.fatherId = @"";
	clientView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5];
	
	shrinkTreeDataBase = [[ShrinkTreeDataBase alloc] initWithDatabaseName:@"mclient.data" withTableName:@"shrinkTree"];
	for(NSMutableDictionary* treeNode in self.treeNodes) {
		[shrinkTreeDataBase insertTreeNode:treeNode withFatherId:@"000000"];
	}
	
	curArray = [[shrinkTreeDataBase getTreeNodeDatas:@"000000" withTag:NO] retain];
	
	selectedArray = [[NSMutableArray arrayWithObject:@"顶级"] retain];
	
	[self addTabBarHeader:[NSMutableArray arrayWithObject:[[[TTTabItem alloc] initWithTitle:@"顶级"] autorelease]]];
	
	tabBarTreeNodes = [[TTTabGrid alloc] initWithFrame:CGRectMake(10, 10, self.width-20, 0)];
	tabBarTreeNodes.backgroundColor = [UIColor clearColor];
	tabBarTreeNodes.delegate = self;
	tabBarTreeNodes.tag = -1;

	NSMutableArray* items = [NSMutableArray array];
	for (NSDictionary* item in curArray) {
		[items addObject:[[[TTTabItem alloc] initWithTitle:[item objectForKey:@"lbl"]] autorelease]];
	}
	tabBarTreeNodes.tabItems = items;
	self.treeNodesItemBack = items;
	
	scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.width, self.height-44-48-44)];
	scrollView.backgroundColor = [UIColor clearColor];
	[scrollView addSubview:tabBarTreeNodes];
	[tabBarTreeNodes sizeToFit];
	scrollView.contentSize = CGSizeMake(self.width, [tabBarTreeNodes sizeThatFits:CGSizeMake(CGRectGetWidth(tabBarTreeNodes.bounds), CGRectGetHeight(scrollView.frame))].height+20);
	[clientView addSubview:scrollView];
	
	self.treeNodePosition = self.treeData;
	
	[self registerNotifications];
}

- (void)viewWillAppear:(BOOL)animated {
	[super viewWillAppear:animated];
	
	NSArray* items = [tabBarTreeNodes.tabItems retain];
	tabBarTreeNodes.tabItems = items;
	[self checkAndAddControl];
}

- (void)viewDidAppear:(BOOL)animated {
	[self registerNotifications];
}

- (void)viewDidDisappear:(BOOL)animated {
	[self unregisterNotifications];
}

- (void)dealloc {
	[treeData release];
	[treeNodes release];
	[treeNodePosition release];
	[curArray release];
	[selectedArray release];
	[scrollView release];
	TT_RELEASE_SAFELY(tabBarHeader);
	TT_RELEASE_SAFELY(tabBarTreeNodes);
	[shrinkTreeDataBase release];
	[treeNodesItemBack release];
	[self unregisterNotifications];
    [super dealloc];
}

- (void)addTabBarHeader:(NSArray*)items {
	UIView* header = [clientView viewWithTag:-2];
	if (header) {
		[header removeFromSuperview];
	}
	tabBarHeader = [[MCTabStrip alloc] initWithFrame:CGRectMake(0, 0, self.width, 44)];
	tabBarHeader.backgroundColor = [UIColor clearColor];
	tabBarHeader.delegate = self;
	tabBarHeader.tag = -2;
	tabBarHeader.selectedTail = YES;
	tabBarHeader.tabItems = items;
	[clientView addSubview:tabBarHeader];
}

-(void)doAction {
	@try{
		NSDictionary* treeNode = [shrinkTreeDataBase getTreeNodeData:[treeNodePosition objectForKey:@"id"] withTag:YES];
		if ([[treeNode objectForKey:@"hc"] boolValue]) {
			[[MServerDAO sharedInstance] getNodeAsync:[treeNode objectForKey:@"nid"] == nil?@"":[treeNode objectForKey:@"nid"]
											   treeId:[treeNode objectForKey:@"id"] == nil?@"":[treeNode objectForKey:@"id"] 
										  queryFilter:[treeNode objectForKey:@"ft"] == nil?[[NSMutableArray alloc]init]:[treeNode objectForKey:@"ft"]
												param:[treeNode objectForKey:@"param"] == nil?[[NSMutableDictionary alloc]init]:[treeNode objectForKey:@"param"]
											 delegate:self];
			return;
		}
		NSMutableDictionary *params = [treeNode objectForKey:@"param"];
		NSMutableDictionary *url = [params objectForKey:@"link"];
		if (url == nil || [@"empty_url" isEqualToString:[url objectForKey:@"actionType"]]) {
			
		}
		
		[MCFunction pushViewByUrl:url parameters:nil confirmMessage:nil naviController:self.navigationController];
	}@catch (NSException *e) {
		[[MCErrorManagement instance] doError:@"99" 
								returnMessage:[NSString stringWithFormat:@"main: Caught %@: %@", [e name], [e reason]]];
	}	
}


#pragma mark -- MCServer2ViewDelegate --
#define TitleHeight              20
#define SearchFieldHeight        25
- (void)textFieldDone:(id)sender
{
	[sender resignFirstResponder];
}
- (void)checkAndAddControl {
	NSDictionary* curtreeNode = nil;
	if (treeNodePosition == treeData) {
		curtreeNode = treeData;
	} else {
		curtreeNode = [shrinkTreeDataBase getTreeNodeData:[treeNodePosition objectForKey:@"id"] withTag:YES];
	}
	
	BOOL hasSearchBar = [[curtreeNode objectForKey:@"prop"] objectForKey:@"search"] ? YES : NO;
	NSString* titleText = [[curtreeNode objectForKey:@"prop"] objectForKey:@"label"];
	
	UIView*  backgroundView = [clientView viewWithTag:-4554];
	UITextField* searchField = (UITextField*)[backgroundView viewWithTag:-1];
	UILabel* titleLabel = (UILabel*)[backgroundView viewWithTag:-2];
	
	int posy = ((titleText && [titleText length] > 0) ? TitleHeight : 0) + (hasSearchBar ? SearchFieldHeight : 0);
	if (backgroundView) {
		CGRect frame = backgroundView.frame;
		frame.size.height = posy+(posy>0?10:0);
		backgroundView.frame = frame;
	} else {
		backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, self.width, posy+(posy>0?10:0))];
		backgroundView.backgroundColor = [UIColor clearColor];//[[UIColor whiteColor] colorWithAlphaComponent:0.8];
		backgroundView.tag = -4554;
		[clientView addSubview:backgroundView];
	}
	
	//查询框处理
	if (hasSearchBar) {//存在查询框
		if (searchField) {
			CGRect frame = searchField.frame;
			frame.origin.y = 5;
			frame.size.height = SearchFieldHeight;
			searchField.frame = frame;
			
			searchField.text = @"";
		} else {
			searchField = [[UITextField alloc] initWithFrame:CGRectMake(10, 5, self.width-20, SearchFieldHeight)];
			searchField.placeholder = @"请输入字母、数字或汉字首字母";
			searchField.borderStyle = UITextBorderStyleRoundedRect;
			searchField.tag = -1;
			searchField.clearButtonMode = UITextFieldViewModeAlways;
			[searchField addTarget:self action:@selector(textFieldDone:) forControlEvents:UIControlEventEditingDidEndOnExit];
			[backgroundView addSubview:searchField];
		}
	} else if (searchField) {//不需要查询框
		[searchField removeFromSuperview];
		searchField = nil;
	}
	//标题栏处理
	if (titleText && [titleText length] > 0) {//存在标题栏
		if (titleLabel) {
			CGRect frame = titleLabel.frame;
			frame.origin.y = CGRectGetHeight(searchField.frame)+10;
			frame.size.height = TitleHeight;
			titleLabel.frame = frame;
			
			titleLabel.text = titleText;
		} else {
			titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, CGRectGetHeight(searchField.frame)+10, self.width-20, TitleHeight)];
			titleLabel.text = titleText;
			titleLabel.tag = -2;
			titleLabel.backgroundColor = [UIColor clearColor];
			[backgroundView addSubview:titleLabel];
		}
	} else if (titleLabel) {//不需要标题栏
		[titleLabel removeFromSuperview];
	}
	
	CGRect frame = scrollView.frame;
	frame.origin.y = CGRectGetMaxY(backgroundView.frame);
	frame.size.height = CGRectGetMaxY(self.view.frame)-frame.origin.y ;
	scrollView.frame = frame;
}

- (void)treeDataSet:(NSMutableDictionary *)returnValue insertFlag:(BOOL)flag {
	NSString* nodeId = [NSString stringWithFormat:@"%@",[treeNodePosition objectForKey:@"id"]];
	BOOL isFirstNode = [[treeNodePosition objectForKey:@"fatherId"] isEqualToString:@"000000"];
	if (flag) {
		for(NSMutableDictionary* treeNode in [returnValue objectForKey:@"ns"]) {
			[shrinkTreeDataBase insertTreeNode:treeNode withFatherId:nodeId];
		}
		if ([returnValue objectForKey:@"prop"]) {
			NSMutableDictionary* node = [shrinkTreeDataBase getTreeNodeData:nodeId withTag:YES];
			[node setObject:[returnValue objectForKey:@"prop"] forKey:@"prop"];
			
			[shrinkTreeDataBase updateTreeNodeData:node withNodeId:nodeId];
		}
	}

	NSMutableArray* array = [[shrinkTreeDataBase getTreeNodeDatas:nodeId withTag:NO] retain];
	[curArray release];
	curArray = array;
	
	if (isFirstNode) {
		NSRange range;
		range.location = 1;
		range.length = [selectedArray count] - 1;
		[selectedArray removeObjectsInRange:range];
		[selectedArray addObject:treeNodePosition];
	} else {
		int index = -1;
		for (int i = 0; i < [selectedArray count]; i++) {
			if (treeNodePosition == [selectedArray objectAtIndex:i]) {
				index = i;
				break;
			}
		}
		if (index < 0) {
			[selectedArray addObject:treeNodePosition];
		} else if (index < [selectedArray count]-1){
			NSRange range;
			range.location = index+1;
			range.length = [selectedArray count] - index - 1;
			[selectedArray removeObjectsInRange:range];
		}
	}
	NSMutableArray* titles = [NSMutableArray array];
	for (NSDictionary* item in selectedArray) {
		[titles addObject:[[[TTTabItem alloc] initWithTitle:[item isKindOfClass:[NSString class]]? item : [item objectForKey:@"lbl"]] autorelease]];
	}
	[self addTabBarHeader:titles];
	[self checkAndAddControl];
	
	NSMutableArray* items = [NSMutableArray array];
	for (NSDictionary* item in curArray) {
		[items addObject:[[[TTTabItem alloc] initWithTitle:[item objectForKey:@"lbl"]] autorelease]];
	}
	tabBarTreeNodes.tabItems = items;
	self.treeNodesItemBack = items;
	if ([items count] > 0) {
		[tabBarTreeNodes sizeToFit];
		scrollView.contentSize = CGSizeMake(self.width, [tabBarTreeNodes sizeThatFits:CGSizeMake(CGRectGetWidth(tabBarTreeNodes.bounds), CGRectGetHeight(scrollView.frame))].height+20);
		scrollView.contentOffset = CGPointZero;
	} else {
		CGRect frame = tabBarTreeNodes.frame;
		frame.size.height = 0;
		tabBarTreeNodes.frame = frame;
		
		scrollView.contentSize = CGSizeMake(scrollView.contentSize.width, 0);
		scrollView.contentOffset = CGPointZero;
		return;
	}
}
- (void)getDataFromServerSuccess: (NSMutableDictionary *)returnValue {
	if ([returnValue objectForKey:@"ns"]) {
		[self treeDataSet:returnValue insertFlag:YES];
	} else {
		NSMutableDictionary *url = [returnValue objectForKey:@"link"];
		if (url) {
			[MCFunction pushViewByUrl:url parameters:nil confirmMessage:nil naviController:self.navigationController];
		}
	}

}

- (void)tabBar:(TTTabBar*)tabBar tabSelected:(NSInteger)selectedIndex
{
	NSMutableDictionary *treeNode = nil;
	if (tabBar == tabBarTreeNodes) {
		treeNode = [curArray objectAtIndex:selectedIndex];
		[self onSelectedTreeNode:treeNode];
	} else if (tabBar == tabBarHeader) {
		if (selectedIndex == 0) {
			NSMutableArray* array = [[shrinkTreeDataBase getTreeNodeDatas:@"000000" withTag:NO] retain];
			[curArray release];
			curArray = array;
			
			[selectedArray release];
			selectedArray = [[NSMutableArray arrayWithObject:@"顶级"] retain];
			
			[self addTabBarHeader:[NSMutableArray arrayWithObject:[[[TTTabItem alloc] initWithTitle:@"顶级"] autorelease]]];

			self.treeNodePosition = self.treeData;
			[self checkAndAddControl];
			
			NSMutableArray* items = [NSMutableArray array];
			for (NSDictionary* item in curArray) {
				[items addObject:[[[TTTabItem alloc] initWithTitle:[item objectForKey:@"lbl"]] autorelease]];
			}
			tabBarTreeNodes.tabItems = items;
			self.treeNodesItemBack = items;
			[tabBarTreeNodes sizeToFit];
			scrollView.contentSize = CGSizeMake(self.width, [tabBarTreeNodes sizeThatFits:CGSizeMake(CGRectGetWidth(tabBarTreeNodes.bounds), CGRectGetHeight(scrollView.frame))].height+20);
			scrollView.contentOffset = CGPointZero;
		} else {
			treeNode = [selectedArray objectAtIndex:selectedIndex];
			[self onSelectedTreeNode:treeNode];
		}
	}
}

- (void)onSelectedTreeNode:(NSMutableDictionary*)treeNode {
	[treeNodePosition release];
	treeNodePosition = [treeNode retain];
	if ([[treeNode objectForKey:@"hc"] boolValue]) {
		if ([shrinkTreeDataBase childNodesExist:[treeNode objectForKey:@"id"]]) {
			[self treeDataSet:treeNode insertFlag:NO];
			return;
		}
	}
	[self doAction];
}

- (NSString*)firstAlphabet:(NSString*)text {
	return [MCUIToolkit getChineseSpell:text];
}

- (void)onSearchTreeNode:(NSString*)info {
	
	if (!info || [info isEqualToString:@""]) {
		tabBarTreeNodes.tabItems = self.treeNodesItemBack;
	} else {
		NSMutableArray* array = [NSMutableArray array];
		for (TTTabItem* item in self.treeNodesItemBack) {
			NSString* alphabet = [[self firstAlphabet:item.title] uppercaseString];
			if ([alphabet hasPrefix:[info uppercaseString]]) {
				[array addObject:item];
			}
		}
		
		tabBarTreeNodes.tabItems = array;
	}

	[tabBarTreeNodes sizeToFit];
	scrollView.contentSize = CGSizeMake(self.width, [tabBarTreeNodes sizeThatFits:CGSizeMake(CGRectGetWidth(tabBarTreeNodes.bounds), CGRectGetHeight(scrollView.frame))].height+20);
	scrollView.contentOffset = CGPointZero;
}

- (void)TextFieldTextChange:(NSNotification*)aNotification {
	UITextField* inputCtrl = (UITextField*)aNotification.object;
	[self onSearchTreeNode:inputCtrl.text];
}

- (NSString*)selectedTitle {
	NSString* title = nil;
	for (int i = 0; i < [curArray count]; i++) {
		NSDictionary* item = [curArray objectAtIndex:i];
		if (i == 0) {
			title = [item objectForKey:@"lbl"];
			continue;
		}
		title = [title stringByAppendingFormat:@"/%@", [item objectForKey:@"lbl"]];
	}
	
	return title;
}
@end

@interface ShrinkTreeDataBase(Private)
- (BOOL) createTreeDataTable:(sqlite3*)db;
- (BOOL) open:(NSString*)name;
@end

@implementation ShrinkTreeDataBase
@synthesize isOpened = _isOpened;
@synthesize tableName = _tableName;

- (id)initWithDatabaseName:(NSString*)name withTableName:(NSString*)tableName{
	if (self = [super init]) {
		self.tableName = tableName;
		_sqlBuf = malloc(512);
		_isOpened = [self open:name];
	}
	
	return self;
}
- (void)dealloc {
	if(_database) {
		sqlite3_close(_database);
		//free(_database);
		_database = nil;
	}
	free(_sqlBuf);
	[_tableName release];
	[super dealloc];
}

//【1】创建表格
//创建表格
//说明一下，id为表格的主键，必须有。
- (BOOL) createTreeDataTable:(sqlite3*)db {
	NSString* sql = [NSString stringWithFormat:@"CREATE TABLE %@ (id integer,"
					 @"%@ text, %@ text, %@ text, %@ BLOB, %@ integer, %@ integer, PRIMARY KEY(%@, %@))",
					 _tableName, shrinkTreeDB_NodeId, shrinkTreeDB_FatherId, shrinkTreeDB_NodeName, 
					 shrinkTreeDB_NodeData, shrinkTreeDB_NodeDataLen, shrinkTreeDB_hasChild, shrinkTreeDB_NodeId, shrinkTreeDB_FatherId];
	
    sqlite3_stmt *statement;
    if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement:create channels table");
        return NO;
    }
    int success = sqlite3_step(statement);
    sqlite3_finalize(statement);
    if ( success != SQLITE_DONE) {
        MCLog(@"Error: failed to dehydrate:CREATE TABLE channels");
        return NO;
    }
    MCLog(@"Create table 'channels' successed.");
    return YES;
}

//【2】打开数据库，如果没有，那么创建一个
-(BOOL) open:(NSString*)name{
    NSString *path = [[MCFunction documentPath] stringByAppendingPathComponent:name];
    NSFileManager *fileManager = [NSFileManager defaultManager];
	[fileManager removeItemAtPath:path error:nil];
//    BOOL find = [fileManager fileExistsAtPath:path];
//	
//    //找到数据库文件name
//    if (find) {
//        MCLog(@"Database file have already existed.");
//        if(sqlite3_open([path UTF8String], &_database) != SQLITE_OK) {
//            sqlite3_close(_database);
//			_database = nil;
//            MCLog(@"Error: open database file.");
//            return NO;
//        }
//        return YES;
//    }
    if(sqlite3_open([path UTF8String], &_database) == SQLITE_OK) {
		[self truncateTable];
        [self createTreeDataTable:_database];//在后面实现函数createChannelsTable
        return YES;
    } else {
        sqlite3_close(_database);
		_database = nil;
        MCLog(@"Error: open database file.");
        return NO;
    }
    return NO;
}
//【3】向表格中插入一条记录
//假设channle是一个数据结构体，保存了一条记录的内容。
- (BOOL) insertTreeNode:(NSDictionary*)node withFatherId:(NSString*)fatherId{
	NSString* nodeName = [NSString stringWithFormat:@"%@",[node objectForKey:@"lbl"]];
    NSString* nodeId = [NSString stringWithFormat:@"%@-%@-%@", nodeName, [node objectForKey:@"nid"],[node objectForKey:@"id"]];
	NSData*   nodeData = [NSKeyedArchiver archivedDataWithRootObject:node];
	int hasChild = [[node objectForKey:@"hc"] intValue];
	
	sprintf(_sqlBuf, "select count(*) from %s", [_tableName UTF8String]);
	sqlite3_stmt *statement;
	int nCount = 0;
	if (sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement with message:get channels.");
    }
	
	if (sqlite3_step(statement) == SQLITE_ROW) {
		nCount = sqlite3_column_int(statement, 0);
    }
    sqlite3_finalize(statement);
	
	//问号代表未知的值，将在下面将值和字段关联。
	sprintf(_sqlBuf, "INSERT INTO %s (%s,%s,%s,%s,%s,%s,id) VALUES(?,?,?,?,?,?,?)", [_tableName UTF8String],
			[shrinkTreeDB_NodeId UTF8String], [shrinkTreeDB_FatherId UTF8String], [shrinkTreeDB_NodeName UTF8String], 
			[shrinkTreeDB_NodeData UTF8String], [shrinkTreeDB_NodeDataLen UTF8String], [shrinkTreeDB_hasChild UTF8String]);
	
    int success = sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL);
    if (success != SQLITE_OK) {
        MCLog(@"Error: failed to insertTreeNode");
        return NO;
    }
	
	//这里的数字0,1，2，3，4,5代表第几个问号
	int index = 1;
	sqlite3_bind_text(statement, index++, nodeId?[nodeId UTF8String]:[@"" UTF8String], -1, SQLITE_TRANSIENT);
	sqlite3_bind_text(statement, index++, fatherId?[fatherId UTF8String]:[@"" UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, index++, nodeName?[nodeName UTF8String]:[@"" UTF8String], -1, SQLITE_TRANSIENT);
	sqlite3_bind_blob(statement, index++, [nodeData bytes], [nodeData length], SQLITE_TRANSIENT); 
	sqlite3_bind_int (statement, index++, [nodeData length]);
	sqlite3_bind_int (statement, index++, hasChild);
	sqlite3_bind_int (statement, index++, nCount);
	
    success = sqlite3_step(statement);
    sqlite3_finalize(statement);
    
    if (success == SQLITE_ERROR) {
        MCLog(@"Error: failed to insert into the database with message.");
        return NO;
    } 
	
    return YES;
}

//【4】数据库查询
//这里获取表格中所有的记录
- (NSMutableDictionary*) getTreeNodeData:(NSString*)nodeId withTag:(BOOL)isGetNodeData{
    sqlite3_stmt *statement = nil;
	if (isGetNodeData) {//取该节点数据
		sprintf(_sqlBuf, "SELECT DISTINCT %s,%s FROM %s where %s = '%s'",
				[shrinkTreeDB_NodeData UTF8String], [shrinkTreeDB_NodeDataLen UTF8String],[_tableName UTF8String],
				[shrinkTreeDB_NodeId UTF8String], [nodeId UTF8String]);
	} else {//取节点id，父亲id，节点名字
		sprintf(_sqlBuf, "SELECT DISTINCT %s,%s,%s,%s FROM %s where %s = '%s'", 
				[shrinkTreeDB_NodeId UTF8String], [shrinkTreeDB_FatherId UTF8String], [shrinkTreeDB_NodeName UTF8String],[shrinkTreeDB_hasChild UTF8String],
				[_tableName UTF8String], [shrinkTreeDB_NodeId UTF8String], [nodeId UTF8String]);
	}
	
    if (sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement with message:get channels.");
    }
	
	NSMutableDictionary* returnDict = !isGetNodeData ? [NSMutableDictionary dictionary] : nil;
    //查询结果集中一条一条的遍历所有的记录，这里的数字对应的是列值。
    if (sqlite3_step(statement) == SQLITE_ROW) {
		if (!isGetNodeData) {//取该节点数据
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)] forKey:@"id"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)] forKey:@"fatherId"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 2)] forKey:@"lbl"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 3)] forKey:@"hc"];
		} else {//取节点id，父亲id，节点名字
			Byte* data = (Byte*)sqlite3_column_blob(statement, 0);
			int   dataLen = sqlite3_column_int(statement, 1);
			returnDict = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:data length:dataLen]];
		}
    }
    sqlite3_finalize(statement);
	
	return returnDict;
}

//【5】清除所有表数据
- (BOOL) truncateTable {
    sqlite3_stmt *statement = nil;
	
	sprintf(_sqlBuf, "delete from '%s';select * from sqlite_sequence;update sqlite_sequence set seq=0 where name='%s';", 
			[_tableName UTF8String],[_tableName UTF8String]);
    if(sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, nil) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement:truncate %@ table", _tableName);
        return NO;
    }
    int success = sqlite3_step(statement);
    sqlite3_finalize(statement);
    if ( success != SQLITE_DONE) {
        MCLog(@"Error: failed to dehydrate:truncate %@ table", _tableName);
        return NO;
    }
    MCLog(@"truncate %@ table successed.", _tableName);
	return YES;
}

- (NSArray*) getTreeNodeDatas:(NSString*)fatherId withTag:(BOOL)isGetNodeData {
    sqlite3_stmt *statement = nil;
	if (isGetNodeData) {//取该节点数据
		sprintf(_sqlBuf, "SELECT DISTINCT %s,%s FROM %s where %s = '%s' order by id asc",
				[shrinkTreeDB_NodeData UTF8String], [shrinkTreeDB_NodeDataLen UTF8String],[_tableName UTF8String],
				[shrinkTreeDB_FatherId UTF8String], [fatherId UTF8String]);
	} else {//取节点id，父亲id，节点名字
		sprintf(_sqlBuf, "SELECT DISTINCT %s,%s,%s,%s,id FROM %s where %s = '%s' order by id asc", 
				[shrinkTreeDB_NodeId UTF8String], [shrinkTreeDB_FatherId UTF8String], [shrinkTreeDB_NodeName UTF8String],[shrinkTreeDB_hasChild UTF8String],
				[_tableName UTF8String], [shrinkTreeDB_FatherId UTF8String], [fatherId UTF8String]);
	}
	
    if (sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement with message:get channels.");
    }
	
	NSMutableArray* array = [NSMutableArray array];
    //查询结果集中一条一条的遍历所有的记录，这里的数字对应的是列值。
    while (sqlite3_step(statement) == SQLITE_ROW) {
		NSMutableDictionary* returnDict = !isGetNodeData ? [NSMutableDictionary dictionary] : nil;
		if (!isGetNodeData) {//取该节点数据
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)] forKey:@"id"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)] forKey:@"fatherId"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 2)] forKey:@"lbl"];
			[returnDict setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 3)] forKey:@"hc"];
		} else {//取节点id，父亲id，节点名字
			Byte* data = (Byte*)sqlite3_column_blob(statement, 0);
			int   dataLen = sqlite3_column_int(statement, 1);
			returnDict = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:data length:dataLen]];
		}
		[array addObject:returnDict];
    }
    sqlite3_finalize(statement);
	
	return array;
}

- (BOOL) childNodesExist:(NSString*)nodeId
{
	sqlite3_stmt *statement = nil;
	sprintf(_sqlBuf, "SELECT count(*) FROM %s where %s = '%s'",
			[_tableName UTF8String], [shrinkTreeDB_FatherId UTF8String], [nodeId UTF8String]);
	
    if (sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL) != SQLITE_OK) {
        MCLog(@"Error: failed to prepare statement with message:get channels.");
    }

    if (sqlite3_step(statement) == SQLITE_ROW) {
		NSString* count = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
		if ([count intValue] > 0) {
			sqlite3_finalize(statement);
			return YES;
		}
    }
    sqlite3_finalize(statement);
	
	return NO;
}

//【3】更新表中一条数据记录
- (BOOL) updateTreeNodeData:(NSDictionary*)node withNodeId:(NSString*)nodeId{
	NSData*   nodeData = [NSKeyedArchiver archivedDataWithRootObject:node];
	
	sprintf(_sqlBuf, "update %s set %s=?,%s=? where %s='%s'", [_tableName UTF8String], 
			[shrinkTreeDB_NodeData UTF8String], [shrinkTreeDB_NodeDataLen UTF8String], 
			[shrinkTreeDB_NodeId UTF8String], [nodeId UTF8String]);
	sqlite3_stmt *statement;
	
    int success = sqlite3_prepare_v2(_database, _sqlBuf, -1, &statement, NULL);
    if (success != SQLITE_OK) {
        MCLog(@"Error: failed to updateTreeNodeData");
        return NO;
    }
	
	//这里的数字0,1，2，3，4,5代表第几个问号
	int index = 1;
	sqlite3_bind_blob(statement, index++, [nodeData bytes], [nodeData length], SQLITE_TRANSIENT); 
	sqlite3_bind_int (statement, index++, [nodeData length]);
	
    success = sqlite3_step(statement);
    sqlite3_finalize(statement);
    
    if (success == SQLITE_ERROR) {
        MCLog(@"Error: failed to update the database with message.");
        return NO;
    } 
	
    return YES;
}

@end
